home *** CD-ROM | disk | FTP | other *** search
/ Gamers Delight 2 / Gamers Delight 2.iso / Aminet / game / board / UChessSrc.lha / genmoves.c < prev    next >
C/C++ Source or Header  |  1994-05-28  |  11KB  |  462 lines

  1. //#define USE_SIDEBIT 1 // 4PL70 uses SIDEBIT here!!
  2. /*
  3.  * genmoves.c - C source for GNU CHESS
  4.  *
  5.  * Copyright (c) 1988,1989,1990 John Stanback
  6.  * Copyright (c) 1992 Free Software Foundation
  7.  *
  8.  * This file is part of GNU CHESS.
  9.  *
  10.  * GNU Chess is free software; you can redistribute it and/or modify
  11.  * it under the terms of the GNU General Public License as published by
  12.  * the Free Software Foundation; either version 2, or (at your option)
  13.  * any later version.
  14.  *
  15.  * GNU Chess is distributed in the hope that it will be useful,
  16.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18.  * GNU General Public License for more details.
  19.  *
  20.  * You should have received a copy of the GNU General Public License
  21.  * along with GNU Chess; see the file COPYING.  If not, write to
  22.  * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  23.  */
  24. #include "gnuchess.h"
  25.  
  26.  
  27. short __aligned *TrP;
  28.  
  29. #define Link(from,to,flag,s) \
  30. {\
  31.    node->f = from; node->t = to;\
  32.      node->reply = 0;\
  33.        node->flags = flag;\
  34.      node->score = s;\
  35.        ++node;\
  36.          (*TrP)++;\
  37.          }
  38.  
  39. #ifndef KILLTO
  40. inline void
  41. LinkMove (ARGSZ int ply, ARGSZ int f,
  42.       ARGSZ int t,
  43.       ARGSZ int flag,
  44.       ARGSZ int xside)
  45. #else
  46. inline void
  47. LinkMove (ARGSZ int ply, ARGSZ int f,
  48.       ARGSZ int t,
  49.       ARGSZ int flag)
  50. #endif
  51.  
  52. /*
  53.  * Add a move to the tree.  Assign a bonus to order the moves as follows: 1.
  54.  * Principle variation 2. Capture of last moved piece 3. Other captures
  55.  * (major pieces first) 4. Killer moves 5.
  56.  */
  57.  
  58. {
  59.   register short s = 0;
  60. #if defined HISTORY
  61.   register short z;
  62. #endif
  63.   register unsigned short mv;
  64.   register struct leaf *node;
  65.  
  66.   node = &Tree[*TrP];
  67.   mv = (f << 8) | t;
  68. #ifdef KILLT
  69. #ifdef USE_SIDEBIT
  70.   s += killt[mv | sidebit];
  71. #else
  72.   s += killt[mv];
  73. #endif
  74. #endif
  75. #ifdef HISTORY
  76.   z = mv;
  77.   if (xside == white) z |= 0x4000;
  78.   s += history[z];
  79. #endif
  80.   if (color[t] != neutral)
  81.     {
  82.       /* TOsquare is the square the last piece moved moved to */
  83.       s +=  value[board[t]] - board[f] + ((t == TOsquare) ? 500 : 0);
  84.     }
  85.   if (board[f] == pawn)
  86.     if (row (t) == 0 || row (t) == 7)
  87.       {
  88.     flag |= promote;
  89.     s += 800;
  90. #if !defined OLDXBOARD  && !defined GNU3 && !defined CHESSTOOL
  91.     Link (f, t, flag | queen, s - 20000);
  92.     s -= 200;
  93.     Link (f, t, flag | knight, s - 20000);
  94.     s -= 50;
  95.     Link (f, t, flag | rook, s - 20000);
  96.     flag |= bishop;
  97.     s -= 50;
  98. #else
  99.     flag |= queen;
  100. #endif
  101.       }
  102.     else if (row (t) == 1 || row (t) == 6)
  103.       {
  104.     flag |= pwnthrt;
  105.     s += 600;
  106.       }
  107.     else if ((row(t) == ((color[f] == white)?5:2)) && (ply > MINDEPTH) && (ply < Sdepth+3))
  108.       {
  109.     if ((mtl[white] - pmtl[white] + mtl[black] - pmtl[black]) < PTVALUE)
  110.       {
  111.         flag |= pwnthrt;
  112.         s += 400;
  113.       }
  114.       }
  115.   Link (f, t, flag, s - 20000);
  116. }
  117.  
  118. inline
  119. void
  120. GenMoves (ARGSZ int ply, ARGSZ int sq, ARGSZ int side, ARGSZ int xside)
  121.  
  122. /*
  123.  * Generate moves for a piece. The moves are taken from the precalulated
  124.  * array nextpos/nextdir. If the board is free, next move is choosen from
  125.  * nextpos else from nextdir.
  126.  */
  127.  
  128. {
  129.   register short u, piece;
  130.   register unsigned char *ppos, *pdir;
  131.  
  132.   TrP = &TrPnt[ply + 1];
  133.   piece = board[sq];
  134.   ppos = nextpos[ptype[side][piece]][sq];
  135.   pdir = nextdir[ptype[side][piece]][sq];
  136.   if (piece == pawn)
  137.     {
  138.       u = ppos[sq];        /* follow no captures thread */
  139.       if (color[u] == neutral)
  140.     {
  141. #ifndef KILLTO
  142.       LinkMove (ply, sq, u, 0, xside);
  143. #else
  144.       LinkMove (ply, sq, u, 0);
  145. #endif
  146.       u = ppos[u];
  147.       if (color[u] == neutral)
  148. #ifndef KILLTO
  149.         LinkMove (ply, sq, u, 0, xside);
  150. #else
  151.         LinkMove (ply, sq, u, 0);
  152. #endif
  153.     }
  154.       u = pdir[sq];        /* follow captures thread */
  155.       if (color[u] == xside && board[u] != king)
  156. #ifndef KILLTO
  157.     LinkMove (ply, sq, u, capture, xside);
  158. #else
  159.     LinkMove (ply, sq, u, capture);
  160. #endif
  161.       u = pdir[u];
  162.       if (color[u] == xside && board[u] != king)
  163. #ifndef KILLTO
  164.     LinkMove (ply, sq, u, capture, xside);
  165. #else
  166.     LinkMove (ply, sq, u, capture);
  167. #endif
  168.     }
  169.   else
  170.     {
  171.       u = ppos[sq];
  172.       do
  173.     {
  174.       if (color[u] == neutral)
  175.         {
  176. #ifndef KILLTO
  177.           LinkMove (ply, sq, u, 0, xside);
  178. #else
  179.           LinkMove (ply, sq, u, 0);
  180. #endif
  181.           u = ppos[u];
  182.         }
  183.       else
  184.         {
  185.           if (color[u] == xside && board[u] != king)
  186. #ifndef KILLTO
  187.         LinkMove (ply, sq, u, capture, xside);
  188. #else
  189.         LinkMove (ply, sq, u, capture);
  190. #endif
  191.           u = pdir[u];
  192.         }
  193.       } while (u != sq);
  194.     }
  195. }
  196.  
  197. void
  198. MoveList (INTSIZE int side, INTSIZE int ply)
  199.  
  200. /*
  201.  * Fill the array Tree[] with all available moves for side to play. Array
  202.  * TrPnt[ply] contains the index into Tree[] of the first move at a ply.
  203.  */
  204.  
  205. {
  206.   register short i, xside, f;
  207.  
  208.   xside = side ^ 1;
  209.   TrP = &TrPnt[ply + 1];
  210.   *TrP = TrPnt[ply];
  211.   if (!PV)
  212.     Swag0 = killr0[ply];
  213.    else Swag0 = PV;
  214.   Swag1 = killr1[ply];
  215.   Swag2 = killr2[ply];
  216.   Swag3 = killr3[ply];
  217.   if (ply > 2)
  218.     Swag4 = killr1[ply - 2]; else Swag4 = 0;
  219. #ifdef KILLT
  220. #ifdef USE_SIDEBIT
  221.   sidebit = ((side == white) ? 0 : 0x80);
  222.   killt[SwagHt | sidebit] += 5000;
  223.   killt[Swag0 | sidebit] += 2000;
  224.   killt[Swag1 | sidebit] += 60;
  225.   killt[Swag2 | sidebit] += 50;
  226.   killt[Swag3 | sidebit] += 40;
  227.   killt[Swag4 | sidebit] += 30;
  228. #else
  229.   killt[SwagHt] += 5000;
  230.   killt[Swag0] += 2000;
  231.   killt[Swag1] += 60;
  232.   killt[Swag2] += 50;
  233.   killt[Swag3] += 40;
  234.   killt[Swag4] += 30;
  235. #endif
  236. #endif
  237. #ifdef HISTORKILLT
  238. #ifdef HISTORY
  239.   i = (side == black)?0x4000:0;
  240.   history[SwagHt | i] += 5000;
  241.   history[Swag0 | i] += 2000;
  242.   history[Swag1 | i] += 60;
  243.   history[Swag2 | i] += 50;
  244.   history[Swag3 | i] += 40;
  245.   history[Swag4 | i] += 30;
  246. #endif
  247. #endif
  248.   for (i = PieceCnt[side]; i >= 0; i--)
  249.     GenMoves (ply, PieceList[side][i], side, xside);
  250.   if (!castld[side])
  251.     {
  252.       f = PieceList[side][0];
  253.       if (castle (side, f, f + 2, 0))
  254.     {
  255. #ifndef KILLTO
  256.       LinkMove (ply, f, f + 2, cstlmask, xside);
  257. #else
  258.       LinkMove (ply, f, f + 2, cstlmask);
  259. #endif
  260.     }
  261.       if (castle (side, f, f - 2, 0))
  262.     {
  263. #ifndef KILLTO
  264.       LinkMove (ply, f, f - 2, cstlmask, xside);
  265. #else
  266.       LinkMove (ply, f, f - 2, cstlmask);
  267. #endif
  268.     }
  269.     }
  270.     if (epsquare > 0)
  271.       {
  272.       register SHORT l;
  273.  
  274.       f = epmove1[epsquare];
  275.       if (color[f] == side && board[f] == pawn)
  276.         {
  277.         l = epsquare + ((epsquare > f) ? -8 : 8);
  278.         board[l] = no_piece;
  279.         color[l] = neutral;
  280.               LinkMove (ply, f, epsquare, capture | epmask, xside);
  281.         board[l] = pawn;
  282.         color[l] = xside;
  283.         }
  284.       f = epmove2[epsquare];
  285.       if (color[f] == side && board[f] == pawn)
  286.         {
  287.         l = epsquare + ((epsquare > f) ? -8 : 8);
  288.         board[l] = no_piece;
  289.         color[l] = neutral;
  290.               LinkMove (ply, f, epsquare, capture | epmask, xside);
  291.         board[l] = pawn;
  292.         color[l] = xside;
  293.         }
  294.       }
  295. #ifdef KILLT
  296. #ifdef USE_SIDEBIT
  297.   killt[SwagHt | sidebit] -= 5000;
  298.   killt[Swag0 | sidebit] -= 2000;
  299.   killt[Swag1 | sidebit] -= 60;
  300.   killt[Swag2 | sidebit] -= 50;
  301.   killt[Swag3 | sidebit] -= 40;
  302.   killt[Swag4 | sidebit] -= 30;
  303. #else
  304.   killt[SwagHt] -= 5000;
  305.   killt[Swag0] -= 2000;
  306.   killt[Swag1] -= 60;
  307.   killt[Swag2] -= 50;
  308.   killt[Swag3] -= 40;
  309.   killt[Swag4] -= 30;
  310. #endif
  311. #endif
  312. #ifdef HISTORKILLT
  313. #ifdef HISTORY
  314.  i = (side == black)?0x4000:0;
  315.   history[SwagHt | i] -= 5000;
  316.   history[Swag0 | i] -= 2000;
  317.   history[Swag1 | i] -= 60;
  318.   history[Swag2 | i] -= 50;
  319.   history[Swag3 | i] -= 40;
  320.   history[Swag4 | i] -= 30;
  321. #endif
  322. #endif
  323.   SwagHt = 0;            /* SwagHt is only used once */
  324.   GenCnt += (TrPnt[ply+1] - TrPnt[ply]);
  325. }
  326.  
  327. void
  328. CaptureList (INTSIZE int side, INTSIZE int ply)
  329.  
  330. /*
  331.  * Fill the array Tree[] with all available cature and promote moves for side
  332.  * to play. Array TrPnt[ply] contains the index into Tree[] of the first move
  333.  * at a ply.
  334.  */
  335.  
  336. {
  337.   register short u, sq, xside;
  338.   register struct leaf *node;
  339.   register unsigned char *ppos, *pdir;
  340.   short i, piece, *PL, r7;
  341.  
  342.   xside = side ^ 1;
  343.   TrP = &TrPnt[ply + 1];
  344.   *TrP = TrPnt[ply];
  345.   node = &Tree[*TrP];
  346.   r7 = rank7[side];
  347.   PL = PieceList[side];
  348. #ifdef KILLT // 4PL70 USES sidebit here!!
  349. #ifdef USE_SIDEBIT
  350.   sidebit = ((side == white) ? 0 : 0x80);
  351.   killt[SwagHt | sidebit] += 5000;
  352.   killt[Swag0 | sidebit] += 2000;
  353.   killt[Swag1 | sidebit] += 60;
  354.   killt[Swag2 | sidebit] += 50;
  355.   killt[Swag3 | sidebit] += 40;
  356.   killt[Swag4 | sidebit] += 30;
  357. #else
  358.   killt[SwagHt] += 5000;
  359.   killt[Swag0] += 2000;
  360.   killt[Swag1] += 60;
  361.   killt[Swag2] += 50;
  362.   killt[Swag3] += 40;
  363.   killt[Swag4] += 30;
  364. #endif
  365. #endif
  366.  
  367.     for (i = 0; i <= PieceCnt[side]; i++)
  368.       {
  369.       SHORT r = row(PieceList[xside][0]);
  370.       SHORT c = column(PieceList[xside][0]);
  371.       sq = PL[i];
  372.       piece = board[sq];
  373.       if (sweep[piece])
  374.         {
  375.         ppos = nextpos[piece][sq];
  376.         pdir = nextdir[piece][sq];
  377.         u = ppos[sq];
  378.         do
  379.           {
  380.               if (color[u] == neutral) {
  381.                 if (piece == rook | piece == queen) {
  382.                 if(r == row(sq) || c == column(sq)) Link (sq, u, 0, -999);}
  383.                 else if(abs(r - row(sq)) == abs(c - column(sq)))Link (sq, u, 0, -999);
  384.             u = ppos[u];}
  385.               else
  386.             {
  387.                 if (color[u] == xside) Link (sq, u, capture, value[board[u]] + svalue[u] - piece);
  388.                 u = pdir[u];
  389.             }
  390.           }
  391.         while (u != sq);
  392.         }
  393.       else
  394.         {
  395.         pdir = nextdir[ptype[side][piece]][sq];
  396.         if (piece == pawn && row (sq) == r7)
  397.           {
  398.               u = pdir[sq];
  399.               if (color[u] == xside){
  400.               Link (sq, u, capture | promote | queen, valueQ);
  401. #if !defined OLDXBOARD  && !defined GNU3 && !defined CHESSTOOL
  402.                 Link (sq, u, capture | promote | knight, valueN);
  403.                 Link (sq, u, capture | promote | rook, valueR);
  404.                 Link (sq, u, capture | promote | bishop, valueB);
  405. #endif
  406.               }
  407.               u = pdir[u];
  408.               if (color[u] == xside)
  409.             {
  410.                 Link (sq, u, capture | promote | queen, valueQ);
  411. #if !defined OLDXBOARD  && !defined GNU3 && !defined CHESSTOOL
  412.                 Link (sq, u, capture | promote | knight, valueN);
  413.                 Link (sq, u, capture | promote | rook, valueR);
  414.                 Link (sq, u, capture | promote | bishop, valueB);
  415. #endif
  416.             }
  417.               ppos = nextpos[ptype[side][piece]][sq];
  418.               u = ppos[sq];    /* also generate non capture promote */
  419.               if (color[u] == neutral)
  420.             {
  421.                 Link (sq, u, promote | queen, valueQ);
  422. #if !defined OLDXBOARD  && !defined GNU3 && !defined CHESSTOOL
  423.                 Link (sq, u, promote | knight, valueN);
  424.                 Link (sq, u, promote | rook, valueR);
  425.                 Link (sq, u, promote | bishop, valueB);
  426. #endif
  427.             }
  428.           }
  429.         else
  430.           {
  431.               u = pdir[sq];
  432.               do
  433.             {
  434.                 if (color[u] == xside)
  435.                 Link (sq, u, capture, value[board[u]] + svalue[u] - piece);
  436.                 u = pdir[u];
  437.             }
  438.               while (u != sq);
  439.           }
  440.         }
  441.       }
  442. #ifdef KILLT
  443. #ifdef USE_SIDEBIT // 4PL70 uses SIDEBIT here!!
  444.   sidebit = ((side == white) ? 0 : 0x80);
  445.   killt[SwagHt | sidebit] -= 5000;
  446.   killt[Swag0 | sidebit] -= 2000;
  447.   killt[Swag1 | sidebit] -= 60;
  448.   killt[Swag2 | sidebit] -= 50;
  449.   killt[Swag3 | sidebit] -= 40;
  450.   killt[Swag4 | sidebit] -= 30;
  451. #else
  452.   killt[SwagHt] -= 5000;
  453.   killt[Swag0] -= 2000;
  454.   killt[Swag1] -= 60;
  455.   killt[Swag2] -= 50;
  456.   killt[Swag3] -= 40;
  457.   killt[Swag4] -= 30;
  458. #endif
  459. #endif
  460.   SwagHt = 0;            /* SwagHt is only used once */
  461. }
  462.